/*
 * Copyright (c) 2011 Ondrej Lapacek
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you
 * may not use this file except in compliance with the License. You may
 * obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

/**
 * @author      Ondrej Lapacek
 * @version     1.0, 09/12/11
 * @since       1.0
 */

package cz.muni.fi.android.assistivecamera.texttospeech;

import java.util.Locale;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.Message;
import android.speech.tts.TextToSpeech;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import cz.muni.fi.android.assistivecamera.R;
import cz.muni.fi.android.assistivecamera.dialog.BlindDialog;
import cz.muni.fi.android.assistivecamera.dialog.ResponseEventListener;

public class SpeechHandler implements ResponseEventListener {

	private TextToSpeech mTts;
	private static SpeechHandler ttsThread;
	private static boolean mTtsInitialized;
	private static Context ctx;	
	private static BlindDialog customizeDialog = null;
	
	// Free up resources when the TTS is done being used
    public void TTSDestroy() {
        mTts.shutdown();
    }

    // Set the context for the TTS
    public void ttsSetContext(Context context) {
            mTtsInitialized = false;
            ctx = context;
            
            mTts = new TextToSpeech(ctx, ttsInitListener);
            
            MyPhoneStateListener phoneListener = new MyPhoneStateListener();
            TelephonyManager telephony = (TelephonyManager)ctx.getSystemService(Context.TELEPHONY_SERVICE);
            telephony.listen(phoneListener,PhoneStateListener.LISTEN_CALL_STATE);
    }
	    
    // Initialization of the TTS, set the listener
    private final TextToSpeech.OnInitListener ttsInitListener = new TextToSpeech.OnInitListener() {
    	public void onInit(int status) {
    		//Locale loc = new Locale("cs", "CZ");
			//Locale loc = new Locale("en", "US");
			Locale loc = Locale.getDefault();
			Log.i("SpeechHandler",loc.toString());
			switch (mTts.isLanguageAvailable(loc)) 
			{
				case TextToSpeech.LANG_AVAILABLE:
			    case TextToSpeech.LANG_COUNTRY_AVAILABLE:
			    case TextToSpeech.LANG_COUNTRY_VAR_AVAILABLE:
			        mTts.setLanguage(loc);
			        mTtsInitialized = true;
			        break;
			    case TextToSpeech.LANG_MISSING_DATA:
			    	builtSpeechDialog();
			        mTts.shutdown();
			        mTtsInitialized = false;
			        break;
			    case TextToSpeech.LANG_NOT_SUPPORTED:
			    	builtSpeechDismissDialog();
			        mTtsInitialized = false;
			        break;
			}
        }
    };
 
    public void builtSpeechDismissDialog() {
    	String title = ctx.getResources().getString(R.string.speechStatusDialog);
    	title = title + ": " + ctx.getResources().getString(R.string.notSupportedLanguage);
    	String[] names = {ctx.getResources().getString(R.string.exitAppDialog)};
        customizeDialog = new BlindDialog(ctx, this, title, names);
        customizeDialog.setCancelable(false);
        customizeDialog.show();
    }
    
    public void builtSpeechDialog() {
    	String title = ctx.getResources().getString(R.string.speechStatusDialog);
    	title = title + ": " + ctx.getResources().getString(R.string.speechDisabled);
    	String[] names = {ctx.getResources().getString(R.string.enableSpeechDialog),
    			ctx.getResources().getString(R.string.exitAppDialog)};
        customizeDialog = new BlindDialog(ctx, this, title, names);
        customizeDialog.setCancelable(false);
        customizeDialog.show();
    }
    
    // Queue the message
    public static void ttsQueue(String text, int append, int canSpeak) {
            final Message msg = SpeechHandler.getInstance().mHandler.obtainMessage(R.id.TTS_service, text);
            msg.arg1 = canSpeak;
            msg.arg2 = append;
            
            Thread thread = new Thread() {
                @Override
                public void run() {
                	while(!mTtsInitialized) {

                	}
                	SpeechHandler.getInstance().mHandler.sendMessage(msg);
                }
            };
            thread.start();
    }

    private final Handler mHandler = new Handler() {
    	public void handleMessage(Message msg) {
        	if (mTtsInitialized) {
                switch (msg.what) {
                case R.id.TTS_service:
                	if (ScreenReader.isRunning(ctx)) {
    					if (msg.arg1 != 0) {
    						if (msg.arg2 != 0) mTts.speak((String)msg.obj, TextToSpeech.QUEUE_ADD, null);
    						else mTts.speak((String)msg.obj, TextToSpeech.QUEUE_FLUSH, null);	
    					}
    				} else {
    					if (msg.arg2 != 0) mTts.speak((String)msg.obj, TextToSpeech.QUEUE_ADD, null);
    					else mTts.speak((String)msg.obj, TextToSpeech.QUEUE_FLUSH, null);	
    				}
                	break;
                default:
                	
                }
            }
        }
    };
    
    // Create an instance of the class
    private SpeechHandler() {
            ttsThread = this;
            mTtsInitialized = false;
    }

    // Return the instance of the class
    public static SpeechHandler getInstance() {
            if (ttsThread == null)
                    ttsThread = new SpeechHandler();
            return ttsThread;
    }

    // Return the instance of the class
    public static boolean getSpeechInitialization() {
            return mTtsInitialized;
    }

    public static void setSpeechInitialization(boolean initialization) {
        mTtsInitialized = initialization;
    }
    
    // Stop the speaking TTS
    public void ttsStop() {
    	if (mTts != null) {
        	mTts.stop();
        }
    } 
    
    public class MyPhoneStateListener extends PhoneStateListener {
    	public void onCallStateChanged(int state, String incomingNumber) {
        	switch (state)
            {
            	case TelephonyManager.CALL_STATE_RINGING:
            		ttsStop();
            		break;
                case TelephonyManager.CALL_STATE_OFFHOOK:
                    break;
                case TelephonyManager.CALL_STATE_IDLE:
                	//TODO reactivating tts queue after suspend call TextToSpeech synthesizeToFile()
                    break;
                default:
                    break;
            }
    	}
    }

	@Override
	public void responseEvent(String response) {
		customizeDialog.hide();
		customizeDialog.dismiss();
		if (response.equals(ctx.getResources().getString(R.string.enableSpeechDialog))) {
			/** application redirection to market **/
	    	Intent installIntent = new Intent();
	    	installIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
	        installIntent.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
	        ctx.startActivity(installIntent);
		} else if (response.equals(ctx.getResources().getString(R.string.exitAppDialog))) {
			((Activity) ctx).finish();
		}
	}
}